package com.kx.center.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.kx.center.entity.Channel;
import com.kx.center.entity.ScTrade;
import com.kx.center.entity.ScTradeDetail;
import com.kx.center.entity.Trade;
import com.kx.center.entity.huiyin.Merchant;
import com.kx.center.entity.huiyin.MtOrder;
import com.kx.center.entity.huiyin.PayTranLog;
import com.kx.center.entity.huiyin.SaleOrder;
import com.kx.center.entity.huiyin.SaleOrderPay;
import com.kx.center.entity.huiyin.TradePoi;
import com.kx.center.entity.query.QueryResult;
import com.kx.center.entity.query.QueryTrade;
import com.kx.center.mappers.ChannelMapper;
import com.kx.center.mappers.TradeDetailMapper;
import com.kx.center.mappers.TradeMapper;
import com.kx.center.service.TradeService;
import com.kx.center.util.DateUtil;
import com.kx.center.util.JSONParser;
import com.kx.center.util.StringUtil;

@Service
public class TradeServiceImpl implements TradeService {

	@Autowired
	private TradeMapper tradeMapper;
	@Autowired
	private TradeDetailMapper tradeDetailMapper;
	@Autowired
	private ChannelMapper channelMapper;

	@Override
	public void insertSaleOrder(SaleOrder saleOrder) {
		tradeMapper.insertSaleOrder(saleOrder);
	}

	@Override
	public void insertSaleOrderPay(SaleOrderPay saleOrderPay) {
		tradeMapper.insertSaleOrderPay(saleOrderPay);
	}

	@Override
	public void insertMerchant(Merchant merchant) {
		tradeMapper.insertMerchant(merchant);
	}

	@Override
	public void insertPayTranLog(PayTranLog payTranLog) {
		tradeMapper.insertPayTranLog(payTranLog);
	}

	@Override
	public void updateMerchant(Merchant merchant) {
		tradeMapper.updateMerchant(merchant);
	}

	@Override
	public void insertTrade(Trade trade) {
		tradeMapper.insertTrade(trade);
	}

	@Override
	public List<TradePoi> findTradeList(QueryTrade queryTrade) {

		List<TradePoi> list = tradeMapper.findTradeList(queryTrade);

		List<TradePoi> list_T = new ArrayList<TradePoi>();
		for (TradePoi t : list) {
			boolean is_add = true;
			for (TradePoi t_T : list_T) {
				if (t_T.getOrderSn().equals(t.getOrderSn())
						&& t_T.getSku().equals(t.getSku())) {
					t_T.setGoodsPayPrice(t.getGoodsPayPrice()
							+ t_T.getGoodsPayPrice());
					is_add = false;
				}
			}
			if (is_add) {
				list_T.add(t);
			}
		}
		return list_T;
	}

	@Override
	public List<Map<String, Object>> createExcelRecord(List<TradePoi> tradePoi) {
		List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("sheetName", "订单明细报表");
		listmap.add(map);
		TradePoi t = null;
		for (int j = 0; j < tradePoi.size(); j++) {
			t = tradePoi.get(j);
			Map<String, Object> mapValue = new HashMap<String, Object>();
			mapValue.put("1", t.getOrderSn());
			mapValue.put("2", t.getOrderAmount());
			mapValue.put("3", t.getShippingFee());
			mapValue.put("4", t.getGoodsPayPrice());
			mapValue.put("5", t.getGoodsNum());
			mapValue.put("6", t.getSku());
			mapValue.put("7", t.getGoodsName());
			mapValue.put("8", DateUtil.unixTimeToTimestamp(t.getPaymentTime()));
			mapValue.put("9", t.getStoreName());
			mapValue.put("10", t.getChannelId());
			listmap.add(mapValue);
		}
		return listmap;
	}

	@Override
	public Long saleOrderMaxTime() {
		return tradeMapper.saleOrderMaxTime();
	}

	@Override
	public Long saleOrderPayMaxTime() {
		return tradeMapper.saleOrderPayMaxTime();
	}

	@Override
	public List<String> findMerchantIdList() {
		return tradeMapper.findMerchantIdList();
	}

	@Override
	public Long payTranLogMaxTime() {
		return tradeMapper.payTranLogMaxTime();
	}

	@Override
	public List<String> findTradeIdList() {
		return tradeMapper.findTradeIdList();
	}

	@Override
	public List<Trade> findTradeListTwo() {
		return tradeMapper.findTradeListTwo();
	}

	@Override
	public void insertMtOrder(MtOrder mtOrder) {
		tradeMapper.insertMtOrder(mtOrder);
	}

	@Override
	public List<Trade> findMtOrderList() {
		return tradeMapper.findMtOrderList();
	}

	@Override
	@SuppressWarnings("unchecked")
	public void mtSaveScTrade(HashMap<String, Object> data) {

		Integer id = null;

		try {
			ScTrade scTrade = new ScTrade();
			ScTradeDetail scTradeDetail = new ScTradeDetail();
			scTrade.setOuterId(data.get("order_id").toString().trim());
			scTrade.setOrderSn(data.get("wm_order_id_view").toString().trim());
			scTrade.setChannelStoreId(NumberUtils.toInt(data
					.get("app_poi_code").toString().trim()));
			id = scTrade.getChannelStoreId();
			Channel channel = channelMapper.findStoreByChannelStoreId(id);
			scTrade.setStoreName(channel.getStoreName());
			scTrade.setStoreId(channel.getStoreId());
			scTrade.setCtime(DateUtil.unixTimeToTimestamp(NumberUtils
					.toLong(data.get("ctime").toString().trim())));
			scTrade.setUtime(DateUtil.unixTimeToTimestamp(NumberUtils
					.toLong(data.get("utime").toString().trim())));
			scTrade.setGoodsAmount(NumberUtils.toDouble(data
					.get("original_price").toString().trim()));
			scTrade.setOrderAmount(NumberUtils.toDouble(data.get("total")
					.toString().trim()));
			scTrade.setShippingFee(NumberUtils.toDouble(data
					.get("shipping_fee").toString().trim()));
			scTrade.setOrderState(1);
			scTrade.setHasInvoiced(NumberUtils.toInt(data.get("has_invoiced")
					.toString().trim()) == 0 ? 1 : 2);
			scTrade.setInvoiceTitle(data.get("invoice_title").toString().trim());
			scTrade.setOrderMessage(data.get("caution").toString().trim());
			scTrade.setDeliveryTime(data.get("delivery_time").toString().trim()
					.equals("0") ? scTrade.getCtime() : DateUtil
					.unixTimeToTimestamp(NumberUtils.toLong(data
							.get("delivery_time").toString().trim())));
			scTrade.setChannelId(2);
			scTrade.setRecipientName(data.get("recipient_name").toString()
					.trim());
			scTrade.setRecipientPhone(data.get("recipient_phone").toString()
					.trim());
			scTrade.setRecipientAddress(data.get("recipient_address")
					.toString().trim());
			scTrade.setPayType(NumberUtils.toInt(data.get("pay_type")
					.toString().trim()) == 1 ? 2 : 1);
			tradeMapper.insertScTrade(scTrade);
			ArrayList<HashMap<String, Object>> list = (ArrayList<HashMap<String, Object>>) JSONParser
					.parse((String) data.get("detail"),
							new ArrayList<HashMap<String, Object>>().getClass());
			for (HashMap<String, Object> detail : list) {
				scTradeDetail.setTradeId(scTrade.getId());
				scTradeDetail
						.setOuterId(data.get("order_id").toString().trim());
				scTradeDetail.setStoreId(channel.getStoreId());
				scTradeDetail.setCategoryId(detail.get("app_food_code")
						.toString().trim());
				scTradeDetail.setGoodsName(detail.get("food_name").toString()
						.trim());
				scTradeDetail.setSkuId(detail.get("sku_id").toString().trim());
				scTradeDetail.setPrice(NumberUtils.toDouble(detail.get("price")
						.toString().trim()));
				scTradeDetail.setQty(NumberUtils.toInt(detail.get("quantity")
						.toString().trim()));
				scTradeDetail.setBoxNum(NumberUtils.toInt(detail.get("box_num")
						.toString().trim()));
				scTradeDetail.setBoxPrice(NumberUtils.toDouble(detail
						.get("box_price").toString().trim()));
				tradeDetailMapper.insertScTradeDetail(scTradeDetail);
			}
		} catch (Exception e) {
			System.out.println(e);
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public void elmSaveScTrade(String data) {

		Integer id = null;

		try {
			HashMap<String, Object> ordermap = (HashMap<String, Object>) JSONParser
					.parse(data, new HashMap<String, Object>().getClass());
			HashMap<String, Object> list = (HashMap<String, Object>) ordermap
					.get("data");
			ScTrade scTrade = new ScTrade();
			ScTradeDetail scTradeDetail = new ScTradeDetail();
			scTrade.setOuterId(list.get("order_id").toString().trim());
			scTrade.setOrderSn(list.get("order_id").toString().trim());
			scTrade.setChannelStoreId(NumberUtils.toInt(list
					.get("restaurant_id").toString().trim()));
			id = scTrade.getChannelStoreId();
			Channel channel = channelMapper.findStoreByChannelStoreId(id);
			List<String> phonelist = (List<String>) list.get("phone_list");
			for (int i = 0; i < phonelist.size(); i++) {
				String s = phonelist.get(0);
				scTrade.setRecipientPhone(s);
			}
			scTrade.setRecipientAddress(list.get("address").toString().trim());
			scTrade.setCtime(list.get("created_at").toString().trim());
			scTrade.setUtime(list.get("created_at").toString().trim());
			scTrade.setShippingFee(NumberUtils.toDouble(list.get("deliver_fee")
					.toString().trim()));
			scTrade.setDeliveryTime(StringUtil
					.checkString((String) list.get("deliver_time")).toString()
					.trim().equals("") ? scTrade.getCtime() : StringUtil
					.checkString((String) list.get("deliver_time")).toString()
					.trim());
			scTrade.setOrderMessage(StringUtil
					.checkString((String) list.get("description")).toString()
					.trim());
			scTrade.setInvoiceTitle(StringUtil
					.checkString((String) list.get("invoice")).toString()
					.trim());
			scTrade.setHasInvoiced(scTrade.getInvoiceTitle().equals("") ? 1 : 2);
			scTrade.setPayType(NumberUtils.toInt(list.get("is_online_paid")
					.toString().trim()) == 1 ? 1 : 2);
			scTrade.setChannelId(1);
			scTrade.setOrderState(1);
			scTrade.setStoreId(channel.getStoreId());
			scTrade.setStoreName(channel.getStoreName());
			scTrade.setGoodsAmount(NumberUtils.toDouble(list
					.get("original_price").toString().trim()));
			scTrade.setOrderAmount(NumberUtils.toDouble(list.get("total_price")
					.toString().trim()));
			scTrade.setRecipientName(StringUtil
					.checkString((String) list.get("consignee")).toString()
					.trim());
			scTrade.setRecipientAddress(list.get("address").toString().trim());
			tradeMapper.insertScTrade(scTrade);
			HashMap<String, Object> _detailList = (HashMap<String, Object>) list
					.get("detail");
			ArrayList<HashMap<String, Object>> extraList = (ArrayList<HashMap<String, Object>>) _detailList
					.get("extra");
			for (HashMap<String, Object> extra : extraList) {
				scTradeDetail.setTradeId(scTrade.getId());
				scTradeDetail.setStoreId(channel.getStoreId());
				scTradeDetail
						.setOuterId(list.get("order_id").toString().trim());
				scTradeDetail.setCategoryId(extra.get("category_id").toString()
						.trim());
				scTradeDetail.setGoodsName(extra.get("name").toString().trim());
				scTradeDetail.setPrice(NumberUtils.toDouble(extra.get("price")
						.toString().trim()));
				scTradeDetail.setQty(NumberUtils.toInt(extra.get("quantity")
						.toString().trim()));
				scTradeDetail.setSkuId(extra.get("id").toString().trim());
				tradeDetailMapper.insertScTradeDetail(scTradeDetail);
			}
			List<ArrayList<HashMap<String, Object>>> detailList = (List<ArrayList<HashMap<String, Object>>>) _detailList
					.get("group");
			for (ArrayList<HashMap<String, Object>> _map : detailList) {
				for (HashMap<String, Object> map : _map) {
					scTradeDetail.setTradeId(scTrade.getId());
					scTradeDetail.setStoreId(channel.getStoreId());
					scTradeDetail.setOuterId(list.get("order_id").toString()
							.trim());
					scTradeDetail.setCategoryId(map.get("category_id")
							.toString().trim());
					scTradeDetail.setGoodsName(map.get("name").toString()
							.trim());
					scTradeDetail.setPrice(NumberUtils.toDouble(map
							.get("price").toString().trim()));
					scTradeDetail.setQty(NumberUtils.toInt(map.get("quantity")
							.toString().trim()));
					scTradeDetail.setSkuId(map.get("id").toString().trim());
					tradeDetailMapper.insertScTradeDetail(scTradeDetail);
				}
			}
		} catch (Exception e) {
			System.out.println(e);
		}
	}

	@Override
	public void updateScTradeState(ScTrade scTrade) {
		tradeMapper.updateScTradeState(scTrade);
	}

	@Override
	public QueryResult queryTrade(QueryTrade queryTrade) {
		QueryResult result = new QueryResult();
		result.setPage(queryTrade.getPage());
		result.setPageSize(queryTrade.getPageSize());
		result.setTotalRecord(tradeMapper.findScTradeCount(queryTrade));
		result.setData(tradeMapper.findScTradeDetailList(queryTrade));
		return result;
	}

	@Override
	@SuppressWarnings("unchecked")
	public String getTradeJson(Integer storeId) {

		double todayAmount, yesterdayAmount, oneDayAmount, twoDayAmount, threeDayAmount, fourDayAmount, fiveDayAmount, weekTotalAmount;
		int todayGoods, yesterdayGoods, todayOrder, yesterdayOrder, count;
		Date d = new Date(System.currentTimeMillis());
		String date = DateUtil.formatDate(d);
		Date d1 = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24);
		String date1 = DateUtil.formatDate(d1);
		Date d2 = new Date(System.currentTimeMillis() - 2 * 1000 * 60 * 60 * 24);
		String date2 = DateUtil.formatDate(d2);
		Date d3 = new Date(System.currentTimeMillis() - 3 * 1000 * 60 * 60 * 24);
		String date3 = DateUtil.formatDate(d3);
		Date d4 = new Date(System.currentTimeMillis() - 4 * 1000 * 60 * 60 * 24);
		String date4 = DateUtil.formatDate(d4);
		Date d5 = new Date(System.currentTimeMillis() - 5 * 1000 * 60 * 60 * 24);
		String date5 = DateUtil.formatDate(d5);
		Date d6 = new Date(System.currentTimeMillis() - 6 * 1000 * 60 * 60 * 24);
		String date6 = DateUtil.formatDate(d6);
		try {
			todayAmount = tradeMapper.findTradeAmountById(storeId, date);
			yesterdayAmount = tradeMapper.findTradeAmountById(storeId, date1);
			oneDayAmount = tradeMapper.findTradeAmountById(storeId, date2);
			twoDayAmount = tradeMapper.findTradeAmountById(storeId, date3);
			threeDayAmount = tradeMapper.findTradeAmountById(storeId, date4);
			fourDayAmount = tradeMapper.findTradeAmountById(storeId, date5);
			fiveDayAmount = tradeMapper.findTradeAmountById(storeId, date6);
			weekTotalAmount = todayAmount + yesterdayAmount + oneDayAmount
					+ twoDayAmount + threeDayAmount + fourDayAmount
					+ fiveDayAmount;
			todayGoods = tradeMapper.findTradeGoodsById(storeId, date);
			yesterdayGoods = tradeMapper.findTradeGoodsById(storeId, date1);
			todayOrder = tradeMapper.findTradeOrderById(storeId, date);
			yesterdayOrder = tradeMapper.findTradeOrderById(storeId, date1);

			QueryTrade queryTrade = new QueryTrade();
			List<Integer> status = new ArrayList<Integer>();
			List<Integer> refund = new ArrayList<Integer>();

			status.add(1);
			refund.add(0);
			queryTrade.setStoreId(storeId);
			queryTrade.setOrderState(status);
			queryTrade.setRefundState(refund);
			count = tradeMapper.findScTradeCount(queryTrade);

			Map<String, Object> type = new HashMap<String, Object>();
			type.put("status", "success");
			type.put("data", new ArrayList<HashMap<String, Object>>());
			type.put("msg", "");

			ArrayList<HashMap<String, Object>> list = (ArrayList<HashMap<String, Object>>) type
					.get("data");
			HashMap<String, Object> maps = new HashMap<String, Object>();
			maps.put("todayTotalAmount", todayAmount);
			maps.put("todayTotalOrder", todayOrder);
			maps.put("todayTotalGoods", todayGoods);
			maps.put("yesterdayTotalAmount", yesterdayAmount);
			maps.put("yesterdayTotalOrder", yesterdayOrder);
			maps.put("yesterdayTotalGoods", yesterdayGoods);
			maps.put("weekTotalAmount", weekTotalAmount);
			maps.put("newOrderCount", count);
			maps.put("weekAmount", new ArrayList<Object>());
			ArrayList<Object> week = (ArrayList<Object>) maps.get("weekAmount");
			week.add(fiveDayAmount);
			week.add(fourDayAmount);
			week.add(threeDayAmount);
			week.add(twoDayAmount);
			week.add(oneDayAmount);
			week.add(yesterdayAmount);
			week.add(todayAmount);
			list.add(maps);
			return JSONParser.stringify(type);
		} catch (Exception e) {
			e.printStackTrace();
			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put("status", "error");
			map.put("code", "1001");
			map.put("msg", "发生错误");
			try {
				return JSONParser.stringify(map);
			} catch (JsonProcessingException e1) {
				e1.printStackTrace();
			}
		}
		return null;
	}

	@Override
	public ScTrade findScTradeById(Integer channelId, Long outerId) {
		return tradeMapper.findScTradeById(channelId, outerId);
	}

	@Override
	public Channel findKeyById(Long outerId) {

		Channel channel = channelMapper.findKeyById(outerId);

		return channel;
	}

	@Override
	public Channel findSecretByKey(Long id) {

		Channel channel = channelMapper.findSecretByKey(id);

		return channel;
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateStatus() {

	}

}